﻿package game.socket {
	import flash.net.Socket;
	import flash.system.Capabilities;
	import flash.system.Security;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.ProgressEvent;
	
	public class SocketPolicy extends Socket {
		
		public function SocketPolicy():void {
			this.endian	= SocketConfig.ENDIAN;
			this.timeout= SocketConfig.TIMEOUT*1000;
			
			this.addEventListener (Event.CLOSE,							closeHandler);
			this.addEventListener (Event.CONNECT,						connectHandler);
			this.addEventListener (IOErrorEvent.IO_ERROR,				ioErrorHandler);
			this.addEventListener (SecurityErrorEvent.SECURITY_ERROR,	securityErrorHandler);
			this.addEventListener (ProgressEvent.SOCKET_DATA,			dataHandler);
			
		}
		
		public function check(data:SocketObject):void {
			Security.loadPolicyFile ( 'xmlsocket://'+data.toString() );
			this.connect(data.host, data.port);
		}
		
		public function get testMode():Boolean { return (Capabilities.playerType=='External' || Capabilities.playerType=='StandAlone' || Capabilities.playerType=='Desktop'); }
		
		private function dataHandler(event:ProgressEvent):void {
			if (this.bytesAvailable == 0) return;
			var result:String = this.readUTFBytes(this.bytesAvailable);
			this.dispatchEvent( new SocketEvent ( SocketEvent.POLICY, null ) );
			close();
		}
		
		private function connectHandler(event:Event):void {
			if (testMode)
				this.writeMultiByte(SocketConfig.POLICY, SocketConfig.CHARSET); 
			else {
				this.dispatchEvent( new SocketEvent ( SocketEvent.POLICY, null ) );
				close();
			}
			
			this.dispatchEvent( new SocketEvent ( SocketEvent.CONNECTED, null ) );
		}
		
		public override function close():void {
			try {
				super.close();
			} catch (e:Error) {
				
			}
		}
		
		private function closeHandler(event:Event):void {
			this.dispatchEvent( new SocketEvent ( SocketEvent.DISCONNECTED, null ) );
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void {
			this.dispatchEvent( new SocketEvent ( SocketEvent.ERROR, null ) );
			this.dispatchEvent( new SocketEvent ( SocketEvent.DISCONNECTED, null ) );
		}
		
		private function securityErrorHandler(event:SecurityErrorEvent):void {
			
			this.dispatchEvent( new SocketEvent ( SocketEvent.ERROR, null ) );
			this.dispatchEvent( new SocketEvent ( SocketEvent.DISCONNECTED, null ) );
		}
	}
	
}